package club.cearnach.web.controller.movie;

import club.cearnach.api.dto.UserDTO;
import club.cearnach.entity.*;
import club.cearnach.api.exception.MovieException;
import club.cearnach.api.exception.RoleNotFoundException;
import club.cearnach.api.exception.UserException;
import club.cearnach.api.exception.UserFavoriteException;
import club.cearnach.api.form.PageBean;
import club.cearnach.api.service.*;
import club.cearnach.api.vo.ResultVO;
import club.cearnach.security.enumeration.RoleEnum;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import javax.validation.constraints.Min;
import javax.validation.constraints.NotBlank;

/**
 * @author 阮胜
 * @date 2018/5/23 17:19
 */
@Controller
@Slf4j
@RequestMapping("/user")
@Api(tags = "用户控制层")
public class UserController {
    private final IUserService userService;
    private final IRoleService roleService;
    private final IUserRateService userRateService;
    private final IUserFavoriteService userFavoriteService;
    private final IMovieService movieService;

    public UserController(IUserService userService, IRoleService roleService, IUserRateService userRateService, IUserFavoriteService userFavoriteService, IMovieService movieService) {
        this.userService = userService;
        this.roleService = roleService;
        this.userRateService = userRateService;
        this.userFavoriteService = userFavoriteService;
        this.movieService = movieService;
    }

    @GetMapping("/detail")
    public String detail(Model model) throws UserException {
        User user = obtainUserAccount();
        model.addAttribute(user);
        return "movie/user-detail";
    }


    @PutMapping("/update")
    @ResponseBody
    public boolean update(UserDTO userDTO) throws UserException {
        User user = obtainUserAccount();
        user.setGender(userDTO.getGender());
        user.setNickname(userDTO.getNickname());
        user.setBirthday(userDTO.getBirthday());
        userService.save(user);
        return true;
    }

    @PutMapping("/changePwd")
    @ResponseBody
    public boolean changePwd(UserDTO userDTO) throws UserException {
        User user = userService.findByAccount(userDTO.getAccount()).orElseThrow(() -> new UserException(UserException.USER_CAN_NOT_FOUNT));
        @NotBlank String oldPassword = userDTO.getOldPassword();
        if (user.getPassword().equalsIgnoreCase(oldPassword)) {
            user.setPassword(userDTO.getNewPassword());
            userService.save(user);
            return true;
        }
        return false;
    }

    @ApiOperation("查重")
    @GetMapping("/exist")
    @ResponseBody
    public boolean isExist(String account, Integer id) {
        return userService.isExist(account, id);
    }

    @PostMapping("/save")
    @ResponseBody
    public boolean save(User user) throws RoleNotFoundException {
        Role role = roleService.findByName(RoleEnum.USER.getRole()).orElseThrow(RoleNotFoundException::new);
        user.setRole(role);
        userService.save(user);
        return true;
    }

    @GetMapping("/favorite/list")
    public String favoriteList(PageBean pageBean, Model model) {
        Page<UserFavorite> userFavoritePage = userFavoriteService.findAllOrderByCreateDate(pageBean);
        model.addAttribute("userFavoriteList", userFavoritePage.getContent());
        model.addAttribute("totalMovies", userFavoritePage.getTotalElements());
        model.addAttribute("totalPage", userFavoritePage.getTotalPages());
        model.addAttribute("currentPage", pageBean.getPage());
        return "movie/user-favorite-list";
    }

    @GetMapping("/rate/list")
    public String rateList(PageBean pageBean, Model model) {
        Page<UserRate> userRatePage = userRateService.findAllOrderByCreateDate(pageBean);
        model.addAttribute("userRateList", userRatePage.getContent());
        return "movie/user-rate-list";
    }

    @GetMapping("/profile")
    public String profile(Model model) throws UserException {
        model.addAttribute(obtainUserAccount());
        return "movie/user-profile";
    }

    private User obtainUserAccount() throws UserException {
        String account = SecurityContextHolder.getContext().getAuthentication().getName();
        return userService.findByAccount(account)
                .orElseThrow(() -> new UserException(UserException.USER_CAN_NOT_FOUNT));

    }

    @GetMapping("/favorite")
    @ResponseBody
    public ResultVO favorite(@Min(1) Integer movieId, boolean isFavorite) throws MovieException, UserException {
        Movie movie = movieService.findById(movieId);
        User user = obtainUserAccount();
        UserMovieId userMovieId = new UserMovieId(user, movie);
        UserFavorite userFavorite = new UserFavorite(userMovieId);
        ResultVO resultVO = new ResultVO();
        if (isFavorite) {
            userFavoriteService.save(userFavorite);
            resultVO.setSuccess(true);
            resultVO.setMsg("收藏成功");
        } else {
            try {
                userFavoriteService.delete(userMovieId);
                resultVO.setSuccess(true);
                resultVO.setMsg("取消收藏成功");
            } catch (UserFavoriteException e) {
                resultVO.setSuccess(false);
                resultVO.setMsg("取消收藏失败");
            }
        }
        return resultVO;
    }
}
